package com.ruoci.redis.consistency;

import com.ruoci.redis.constants.BusinessConstants;
import com.ruoci.redis.entity.Users;
import com.ruoci.redis.response.BasicResponse;
import com.ruoci.redis.response.ResponseCode;
import com.ruoci.redis.service.UsersService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RReadWriteLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

/**
 * @Author yang
 * 失效模式
 * 不是原子操作同样会出现脏数据,加读写锁。
 **/
@Slf4j
@RestController
@RequestMapping("/failureMode")
public class FailureMode {


    @Resource
    private RedissonClient redissonClient;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private UsersService usersService;

    @GetMapping("/consistence")
    @Transactional(rollbackFor = Exception.class)
    public BasicResponse failureMode(){
        RReadWriteLock lock = redissonClient.getReadWriteLock(BusinessConstants.CONSISTENCE_LOCK);
        RLock writeLock = lock.writeLock();
        try {
            if (writeLock.tryLock(BusinessConstants.TIME_100, BusinessConstants.TIME_10, TimeUnit.SECONDS)){
                //更新数据库
                Users users = new Users();
                users.setUserCode("172667");
                users.setUserName("去有风的地方");
                usersService.updateById(users);
                //删除缓存
                redisTemplate.delete(BusinessConstants.USER_DATA);
            }
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return new BasicResponse(ResponseCode.SUCCESS.getCode(), BusinessConstants.SUCCESSFULLY_MODIFIED);
    }
}
